﻿using Common;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Timers;
using System.Windows.Threading;

namespace AutoUpdateConfig
{
    public class LogViewCtrlViewModel : ObservableObject
    {
        #region Variables

        private bool autoRef = false;
        private bool notAutoRef = true;
        private string curHospital;
        private ObservableCollection<LogDBModel> logList;
        private MongoDBHelper dbHelper;
        private System.Timers.Timer timer;
        private DateTime seTime;
        private List<string> roomList;
        private List<string> logTypes;
        private string selectedRoom = "";
        private string selectedType = "";
        private List<int> hours;
        private int startHour;
        private int endHour;

        #endregion

        #region Constructor

        public LogViewCtrlViewModel()
        {
            startHour = DateTime.Now.AddHours(-1).Hour;
            endHour = DateTime.Now.Hour;
            hours = new List<int>();
            for (int i = 0; i < 24; i++)
            {
                hours.Add(i);
            }
            LogList = new ObservableCollection<LogDBModel>();
            roomList = new List<string>();
            roomList.Add(" ");
            for (int i = 1; i < 31; i++)
            {
                roomList.Add(i + "");
            }
            selectedRoom = "1";
            LogTypes = new List<string>() { " ", "info", "error", "deadApp" };
            selectedType = "error";
            SeTime = DateTime.Now;
            timer = new System.Timers.Timer();
            timer.Interval = 2000;
            timer.Elapsed += Timer_Elapsed;
            timer.Start();
        }

        #endregion

        #region Properties

        public string SelectedRoom
        {
            get
            {
                return selectedRoom;
            }
            set
            {
                selectedRoom = value;
                ClearList();
                GetList();
            }
        }

        public string CurHospital
        {
            get
            {
                return curHospital;
            }

            set
            {
                curHospital = value;
                ChangeHospital();
            }
        }

        public ObservableCollection<LogDBModel> LogList
        {
            get
            {
                return logList;
            }

            set
            {
                logList = value;
            }
        }

        public bool AutoRef
        {
            get
            {
                return autoRef;
            }

            set
            {
                autoRef = value;
            }
        }

        public bool NotAutoRef
        {
            get
            {
                return notAutoRef;
            }

            set
            {
                notAutoRef = value;
            }
        }

        public DateTime SeTime
        {
            get
            {
                return seTime;
            }

            set
            {
                DateTime time = new DateTime(value.Year, value.Month, value.Day);
                if (seTime.Equals(time))
                {
                    return;
                }
                seTime = time;
                ClearList();
                
            }
        }
        public List<string> RoomList
        {
            get
            {
                return roomList;
            }

            set
            {
                roomList = value;
            }
        }

        public string SelectedType
        {
            get
            {
                return selectedType;
            }

            set
            {
                selectedType = value;
                ClearList();
                GetList();
            }
        }

        public List<string> LogTypes
        {
            get
            {
                return logTypes;
            }

            set
            {
                logTypes = value;
            }
        }

        public List<int> Hours
        {
            get
            {
                return hours;
            }

            set
            {
                hours = value;
            }
        }

        public int StartHour
        {
            get
            {
                return startHour;
            }

            set
            {
                startHour = value;
                ClearList();
            }
        }

        public int EndHour
        {
            get
            {
                return endHour;
            }

            set
            {
                endHour = value;
                ClearList();
            }
        }

        #endregion

        #region 依赖属性

        #endregion

        #region Event

        #endregion

        #region Private Methods

        private void ClearList()
        {
            ThreadPool.QueueUserWorkItem(delegate
            {
                SynchronizationContext.SetSynchronizationContext(new
                  DispatcherSynchronizationContext(System.Windows.Application.Current.Dispatcher));
                SynchronizationContext.Current.Post(pl =>
                {
                    LogList.Clear();
                }, null);
            });
        }

        private void ChangeHospital()
        {
            Hospital hospital = HospitalConfig.Instance.DicHospitals[curHospital];
            dbHelper = new MongoDBHelper(hospital.Ip, hospital.Port, hospital.DbName);
            ThreadPool.QueueUserWorkItem(delegate
            {
                SynchronizationContext.SetSynchronizationContext(new
                  DispatcherSynchronizationContext(System.Windows.Application.Current.Dispatcher));
                SynchronizationContext.Current.Post(pl =>
                {
                    LogList.Clear();
                }, null);
            });
            GetList();
        }

        


        private void Monitor()
        {
            if (AutoRef)
            {
                GetList();
            }
        }

        #endregion

        #region Public/Protected Methods

        public void GetList()
        {
            if (dbHelper == null) return;
            DateTime start = new DateTime(seTime.Year, seTime.Month, seTime.Day, startHour, 0, 0);
            DateTime end = new DateTime(seTime.Year, seTime.Month, seTime.Day, endHour, 0, 0);
            var filter = Builders<LogDBModel>.Filter;
            IEnumerable<LogDBModel> list;
            FilterDefinition<LogDBModel> query = FilterDefinition<LogDBModel>.Empty;
            //var query = filter.And(filter.Where(O => O.LogType.Contains(selectedType.Trim())),
            //                        filter.Where(O => O.LocalModel.RoomId.Contains(SelectedRoom.Trim())),
            //                        filter.And(filter.Gte("CreateTime", start), filter.Lte("CreateTime", end))
            //    );
            if (string.IsNullOrEmpty(selectedRoom.Trim()) && string.IsNullOrEmpty(selectedType.Trim()))
            {
                query = filter.And(filter.Gte("CreateTime", start), filter.Lte("CreateTime", end));
            }
            else if (string.IsNullOrEmpty(selectedRoom.Trim()) && !string.IsNullOrEmpty(selectedType.Trim()))
            {
                query = filter.And(filter.Eq("LogType", selectedType),
                                   filter.And(filter.Gte("CreateTime", start), filter.Lte("CreateTime", end))
               );
            }
            else if (!string.IsNullOrEmpty(selectedRoom.Trim()) && string.IsNullOrEmpty(selectedType.Trim()))
            {
                query = filter.And(filter.Eq("LocalModel.RoomId", selectedRoom),
                                   filter.And(filter.Gte("CreateTime", start), filter.Lte("CreateTime", end))
               );
            }
            else
            {
                query = filter.And(filter.Eq("LogType", selectedType),
                                   filter.Eq("LocalModel.RoomId", selectedRoom),
                                   filter.And(filter.Gte("CreateTime", start), filter.Lte("CreateTime", end)));
            }
            list = dbHelper.Find(query, "Logs");
            List<LogDBModel> temp = new List<LogDBModel>();
            foreach (var item in list)
            {
                if (logList.Where(O => O._id.Equals(item._id)).Count() == 0)
                {
                    temp.Add(item);
                }
            }
            IEnumerable<LogDBModel> orderList = temp.OrderBy(O => O.CreateTime);
            foreach (var item in orderList)
            {
                //ThreadPool.QueueUserWorkItem(delegate
                //{
                SynchronizationContext.SetSynchronizationContext(new
                  DispatcherSynchronizationContext(System.Windows.Application.Current.Dispatcher));
                SynchronizationContext.Current.Post(pl =>
                {
                    if (LogList.Count > 100)
                    {
                        for (int i = 100; i < LogList.Count; i++)
                        {
                            LogList.RemoveAt(i);
                        }
                    }
                    LogList.Insert(0, item);
                }, null);
                //});
            }
        }

        #endregion

        #region EventHandlers

        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            timer.Stop();
            Monitor();
            timer.Start();
        }

        #endregion
    }
}
